package com.rongmei.jdsync.dto.sync;

import com.rongmei.jdsync.dto.PriceChangeDto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Builder;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

/**
 * 推送结果统计
 *
 * @author dongjun
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Schema(description = "推送结果统计")
public class PushResult {

    @Schema(description = "推送成功数量", example = "85")
    private int successCount;

    @Schema(description = "推送失败数量", example = "5")
    private int failedCount;

    @Schema(description = "推送成功的变更列表")
    private List<PriceChangeDto> successChanges;

    @Schema(description = "推送失败的变更列表")
    private List<PriceChangeDto> failedChanges;

    @Schema(description = "错误信息")
    private String errorMessage;

    @Schema(description = "推送开始时间")
    private LocalDateTime startTime;

    @Schema(description = "推送结束时间")
    private LocalDateTime endTime;

    @Schema(description = "推送耗时（毫秒）")
    private long duration;

    @Schema(description = "推送状态：SUCCESS-全部成功，PARTIAL-部分成功，FAILED-全部失败")
    private PushStatus status;

    /**
     * 推送状态枚举
     */
    public enum PushStatus {
        SUCCESS,    // 全部成功
        PARTIAL,    // 部分成功
        FAILED      // 全部失败
    }

    /**
     * 创建成功结果
     */
    public static PushResult success(List<PriceChangeDto> successChanges) {
        return PushResult.builder()
                .successCount(successChanges.size())
                .failedCount(0)
                .successChanges(successChanges)
                .failedChanges(Collections.emptyList())
                .status(PushStatus.SUCCESS)
                .endTime(LocalDateTime.now())
                .build();
    }

    /**
     * 创建失败结果
     */
    public static PushResult failure(List<PriceChangeDto> failedChanges, String errorMessage) {
        return PushResult.builder()
                .successCount(0)
                .failedCount(failedChanges.size())
                .successChanges(Collections.emptyList())
                .failedChanges(failedChanges)
                .errorMessage(errorMessage)
                .status(PushStatus.FAILED)
                .endTime(LocalDateTime.now())
                .build();
    }

    /**
     * 创建部分成功结果
     */
    public static PushResult partial(List<PriceChangeDto> successChanges, 
                                   List<PriceChangeDto> failedChanges, 
                                   String errorMessage) {
        return PushResult.builder()
                .successCount(successChanges.size())
                .failedCount(failedChanges.size())
                .successChanges(successChanges)
                .failedChanges(failedChanges)
                .errorMessage(errorMessage)
                .status(PushStatus.PARTIAL)
                .endTime(LocalDateTime.now())
                .build();
    }

    /**
     * 创建空结果
     */
    public static PushResult empty() {
        return PushResult.builder()
                .successCount(0)
                .failedCount(0)
                .successChanges(Collections.emptyList())
                .failedChanges(Collections.emptyList())
                .status(PushStatus.SUCCESS)
                .endTime(LocalDateTime.now())
                .build();
    }

    /**
     * 计算成功率
     */
    public double getSuccessRate() {
        int total = successCount + failedCount;
        if (total == 0) return 1.0;
        return (double) successCount / total;
    }

    /**
     * 获取总数量
     */
    public int getTotalCount() {
        return successCount + failedCount;
    }

    /**
     * 是否全部成功
     */
    public boolean isAllSuccess() {
        return failedCount == 0 && successCount > 0;
    }

    /**
     * 是否全部失败
     */
    public boolean isAllFailed() {
        return successCount == 0 && failedCount > 0;
    }

    /**
     * 是否部分成功
     */
    public boolean isPartialSuccess() {
        return successCount > 0 && failedCount > 0;
    }

    /**
     * 设置推送开始时间
     */
    public PushResult markStart() {
        this.startTime = LocalDateTime.now();
        return this;
    }

    /**
     * 设置推送结束时间并计算耗时
     */
    public PushResult markEnd() {
        this.endTime = LocalDateTime.now();
        if (this.startTime != null) {
            this.duration = java.time.Duration.between(startTime, endTime).toMillis();
        }
        return this;
    }

    @Override
    public String toString() {
        return String.format("PushResult{总数=%d, 成功=%d, 失败=%d, 成功率=%.2f%%, 状态=%s, 耗时=%dms}", 
                getTotalCount(), successCount, failedCount, getSuccessRate() * 100, status, duration);
    }
}
